﻿using Sustainalytics.DataLayer;
using Sustainalytics.Utils;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sustainalytics.CompanySearch.StressTest
{
    class Program
    {
        static bool _finished = false;

        static void Main(string[] args)
        {
            // create stress tests
            IEnumerable<CompanySearchStressTestSpec> testSpecs = CreateTestSpecs();

            // create company search repository to run against
            ICompanySearchRepository companySearchRepo = CompanySearchRepository.GetCompanySearchRepository(ConfigurationManager.ConnectionStrings["ClientDW"].ConnectionString);

            CompanySearchStressTestLogger logger = new CompanySearchStressTestLogger();

            // create stress test running test specs against a repository and then logging inside a logger
            CompanySearchStressTest test = new CompanySearchStressTest(testSpecs, companySearchRepo, logger);

            // run stress test
            Task startTestTask = test.RunAsync().ContinueWith(task =>
                {
                    _finished = true;
                });

            Console.WriteLine("Test started. Press ENTER to stop.");


            // prompt user to stop manually
            Task.Factory.StartNew(() =>
                {
                    while (!_finished)
                    {
                        ConsoleKey key = Console.ReadKey().Key;

                        if (key == ConsoleKey.Enter)
                        {
                            test.Stop();
                        }
                    }
                });


            #region Wait
            // wait for stress test to stop and handle cancellation exceptions and exceptions in general
            try
            {
                startTestTask.Wait();
            }
            catch (OperationCanceledException ex)
            {
                Console.WriteLine("Cancelled.");
            }
            catch (AggregateException ex)
            {
                if (ex.InnerExceptions.Any(iex => typeof(OperationCanceledException).IsAssignableFrom(iex.GetType())))
                {
                    // cancellation
                    Console.WriteLine("Cancelled.");
                }
                else
                {
                    Console.WriteLine("ERROR: " + ex.Message);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERROR: " + ex.Message);
            }
            #endregion


            Console.WriteLine("Test stopped.");
            Console.ReadLine();
        }

        /// <summary>
        /// Create specs for running stress tests.
        /// </summary>
        /// <returns> Test specs. </returns>
        private static IEnumerable<CompanySearchStressTestSpec> CreateTestSpecs()
        {
            List<CompanySearchStressTestSpec> testSpecs = new List<CompanySearchStressTestSpec>
            {
                new CompanySearchStressTestSpec(1, 10, 100, "A", new PagingOptions { PageIndex = 1, PageSize = 20 }),
                new CompanySearchStressTestSpec(2, 10, 100, "Corp", new PagingOptions { PageIndex = 1, PageSize = 20 }),
                new CompanySearchStressTestSpec(3, 10, 100, "Metro", new PagingOptions { PageIndex = 1, PageSize = 20 }),
                new CompanySearchStressTestSpec(4, 10, 100, "Narborough Plantations PLC", new PagingOptions { PageIndex = 1, PageSize = 20 }),
                new CompanySearchStressTestSpec(5, 10, 100, "Natural", new PagingOptions { PageIndex = 1, PageSize = 20 }),
                // ISIN
                new CompanySearchStressTestSpec(6, 10, 100, "GB0006226087", new PagingOptions { PageIndex = 1, PageSize = 20 }),
                // SEDOL
                new CompanySearchStressTestSpec(7, 10, 100, "0622608", new PagingOptions { PageIndex = 1, PageSize = 20 }),
                // TICKER
                new CompanySearchStressTestSpec(8, 10, 100, "NBP", new PagingOptions { PageIndex = 1, PageSize = 20 })
            };

            return testSpecs;
        }
    }
}
